﻿// ***********************************************************************
// Assembly         : OSS.BIM
// Author           : tian_
// Created          : 05-16-2018
//
// Last Modified By : tian_
// Last Modified On : 08-23-2018
// ***********************************************************************
// <copyright file="ModelUtil.cs" company="">
//     Copyright ©  2017
// </copyright>
// <summary></summary>
// ***********************************************************************

using System;
using System.IO;
using OsgEarth;
using Osg;
using OSS.BIM.Business.Utility;
using OSS.BIM.Model;
using OSS.BIM.Utility;
using ZFGK.IO;
using ZFGK.OSG.Utility;
using ZFGK.osgEarth.Utility;

namespace OSS.BIM.SceneManage
{
    /// <summary>
    /// Class ModelUtil.
    /// </summary>
    public static class ModelUtil
    {
        /// <summary>
        /// Gets the name of the model group.
        /// </summary>
        /// <param name="modelElement">The model information.</param>
        /// <returns>System.String.</returns>
        public static string GetGroupName(this ModelElement modelElement)
        {
            return modelElement.GetModelGrope().ModelGropeId.ToString();
        }
        /// <summary>
        /// 得到位置 （经纬度）
        /// </summary>
        /// <param name="o">The o.</param>
        /// <returns>Vec3d.</returns>
        public static Vec3d GetLocation(this ModelElement o)
        {
            return o.Location.ParseVec3d();
        }

        /// <summary>
        /// 设置位置
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="location">The map pt.</param>
        public static void SetLocation(this ModelElement o, Vec3d location)
        {
            o.Location = location.ToString();
        }

        /// <summary>
        /// Gets the node data.
        /// </summary>
        /// <param name="userModel">The user model.</param>
        /// <param name="srs">The SRS.</param>
        /// <returns>NodeData.</returns>
//         public static NodeData GetNodeData(this ModelElement userModel, SpatialReference srs)
//         {
//             var globeNode = GetNode(userModel, srs);
// 
//             return new NodeData()
//             {
//                 NodeId = userModel.ModelElementId.ToString(),
//                 Node = globeNode
//             };
//         }
        
        public static Node GetNode(this ModelElement userModel, SpatialReference srs)
        {
            var location = userModel.GetLocation();
            var globeNode = new GeoTransform();
            globeNode.setPosition(new GeoPoint(srs, location));
            globeNode.addChild(userModel.GetNodeInUcs());
            globeNode.Name = userModel.ModelElementId.ToString();
            return globeNode;
        }

        /// <summary>
        /// Gets the node path.
        /// </summary>
        /// <param name="userModelFile">The user model file.</param>
        /// <returns>System.String.</returns>
        public static string GetNodePath(this ModelFile userModelFile)
        {
            return Path.Combine(BmConfigUtil.ModelsPath, userModelFile.ModelFileId + userModelFile.Extension);
        }

        /// <summary>
        /// Gets the node in ucs.
        /// </summary>
        /// <param name="userModel">The user model.</param>
        /// <returns>Node.</returns>
        public static Node GetNodeInUcs(this ModelElement userModel)
        {
            throw new Exception("未处理！");
//             var userModelFile = ModelElementDbUtil.GetModelFile(userModel);
// 
//             var upTrf2 = new MatrixTransform(userModel.GetUcsMatix());
//             var node = ZfModelCache.GetNode(userModelFile.GetNodePath(), userModelFile.Fingerprint);
//             OsgEarth.Registry.shaderGenerator().run(node);
//             upTrf2.addChild(node);
//             return upTrf2;
        }

        /// <summary>
        /// Gets the ucs matix.
        /// </summary>
        /// <param name="userModel">The user model.</param>
        /// <returns>Matrixd.</returns>
        public static Matrixd GetUcsMatix(this ModelElement userModel)
        {
            return userModel.GetScaleMatix() * Matrixd.rotate(userModel.Rotation, new Vec3d(0, 0, 1));
        }

        /// <summary>
        /// Gets the scale matix.
        /// </summary>
        /// <param name="userModel">The user model.</param>
        /// <returns>Matrixd.</returns>
        public static Matrixd GetScaleMatix(this ModelElement userModel)
        {
            return Matrixd.scale(userModel.Scale.ParseVec3d()) * Matrixd.translate(0, 0, userModel.ZOffset);
        }

        /// <summary>
        /// Gets the scale node.
        /// </summary>
        /// <param name="userModel">The user model.</param>
        /// <returns>Node.</returns>
        public static Node GetScaleNode(this ModelElement userModel)
        {
            throw new Exception("未处理！");
//             var userModelFile = ModelElementDbUtil.GetModelFile(userModel);
// 
//             var upTrf2 = new MatrixTransform(userModel.GetScaleMatix());
//             var node = ZfModelCache.GetNode(userModelFile.GetNodePath(), userModelFile.Fingerprint);
//             upTrf2.addChild(node);
//             return upTrf2;
        }
        /// <summary>
        /// Gets the ucs matix.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <returns>Matrixd.</returns>
        public static Matrixd GetUcsMatix(this Project project)
        {
            return Matrixd.rotate(project.Rotation, new Vec3d(0, 0, 1));
        }

        /// <summary>
        /// Gets the location.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <returns>Vec3d.</returns>
        public static Vec3d GetLocation(this Project project)
        {
            return new Vec3d(project.Longitude, project.Latitude, project.Elevation);
        }

        /// <summary>
        /// Gets the group.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="srs">The SRS.</param>
        /// <returns>Group.</returns>
        public static Group GetGroup(this Project project, SpatialReference srs)
        {
            return new MatrixTransform(project.GetUcsMatix() * project.GetLocation().CreateLocalToWorld(srs));
        }

        /// <summary>
        /// Gets the cut fill tif file path.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <returns>System.String.</returns>
        public static string GetCutFillTifFilePath(this Project project)
        {
            string ftiFilePath = Path.Combine(BmConfigUtil.AppDataPath, "TifFiles");
            DirectoryUtil.EnsureDirExist(ftiFilePath);
            return Path.Combine(ftiFilePath, project.ProjectId + ".tif");
        }

        /// <summary>
        /// Gets the cut fill tif file temporary path.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <returns>System.String.</returns>
        public static string GetCutFillTifFileTempPath(this Project project)
        {
            return Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".tif");
        }
    }
}
